package org.lex.collection.tree;

import java.io.PrintWriter;

import org.lex.string.IFormatter;
import org.lex.util.IDataHolder;

public interface ITreeNode extends IDataHolder {
	public void accept(ITreeVisitor visitor);

	// =============================
	// child manipulate method: CRUD
	// =============================

	// ======
	// create
	// ======
	/**
	 * This method should behave:
	 * <ol>
	 * <li>remove <code>child</code> from its parent;
	 * <li>add <code>child</code> to this node;
	 * <li>set <code>child</code>'s parent to <code>this</code>.
	 * </ol>
	 */
	public void addChild(ITreeNode child);

	/**
	 * Adds <code>child</code> to the receiver at <code>index</code>.
	 * <code>child</code> will be messaged with <code>setParent</code>.<br>
	 */
	public void insertChild(ITreeNode child, int index);

	// ========
	// retrieve
	// ========
	public ITreeNode[] getChildren();

	public int getChildCount();

	public ITreeNode getChild(int index);

	public boolean hasChildren();

	// ======
	// update
	// ======

	public ITreeNode getParent();

	/**
	 * This method should behave:
	 * <ol>
	 * <li>remove this node from its parent
	 * <li>set this node's parent to <code>parent</code>
	 * <li>add this node to <code>parent</code>
	 * </ol>
	 * 
	 * @param parent
	 */
	public void setParent(ITreeNode parent);

	public void swap(int a, int b);

	// ======
	// delete
	// ======
	/**
	 * This method should behave:
	 * <ol>
	 * <li>remove <code>child</code> from this node
	 * <li>set <code>child</code>'s parent to <code>null</code>
	 * </ol>
	 */
	public void removeChild(ITreeNode child);

	public void removeChild(int index);

	/**
	 * Release any resource of this <code>ITreeNode</code>
	 */
	public void dispose();

	// ==============
	// toString
	// ==============
	public String toTreeString();

	public void print(String ident, String step, IFormatter<Object> dataPrinter, PrintWriter out);
}